From 73d5db0ee7b1cacd88b32503f59e8bb3624669b5 Mon Sep 17 00:00:00 2001 From: "kaf24@firebug.cl.cam.ac.uk" Date: Mon, 16 May 2005 08:41:49 +0000 Subject: [PATCH] bitkeeper revision 1.1412 (42885ccdKOtsuAfBT7XZ0YtfvWw5Ig) Cleanups for printing debug tracing to the console. Also, rename get_cpu_user_regs -> guest_cpu_user_regs. Signed-off-by: Keir Fraser --- xen/arch/ia64/xenmisc.c | 2 +- xen/arch/x86/domain.c | 8 +-- xen/arch/x86/mm.c | 2 +- xen/arch/x86/traps.c | 91 ++++++++++++++++++++++++++++ xen/arch/x86/vmx_intercept.c | 2 +- xen/arch/x86/vmx_io.c | 2 +- xen/arch/x86/vmx_vmcs.c | 2 +- xen/arch/x86/x86_32/traps.c | 75 ----------------------- xen/arch/x86/x86_64/traps.c | 77 +---------------------- xen/common/domain.c | 5 +- xen/common/schedule.c | 4 +- xen/drivers/char/console.c | 15 +++-- xen/include/asm-x86/x86_32/current.h | 4 +- xen/include/asm-x86/x86_64/current.h | 4 +- 14 files changed, 121 insertions(+), 172 deletions(-) diff --git a/xen/arch/ia64/xenmisc.c b/xen/arch/ia64/xenmisc.c index 5e03a07493..85f0bddc69 100644 --- a/xen/arch/ia64/xenmisc.c +++ b/xen/arch/ia64/xenmisc.c @@ -72,7 +72,7 @@ void grant_table_destroy(struct domain *d) return; } -struct pt_regs *get_cpu_user_regs(void) { return ia64_task_regs(current); } +struct pt_regs *guest_cpu_user_regs(void) { return ia64_task_regs(current); } void raise_actimer_softirq(void) { diff --git a/xen/arch/x86/domain.c b/xen/arch/x86/domain.c index b2595ceac4..22fea7eb82 100644 --- a/xen/arch/x86/domain.c +++ b/xen/arch/x86/domain.c @@ -607,7 +607,7 @@ static void load_segments(struct exec_domain *p, struct exec_domain *n) if ( unlikely(!all_segs_okay) ) { - struct cpu_user_regs *regs = get_cpu_user_regs(); + struct cpu_user_regs *regs = guest_cpu_user_regs(); unsigned long *rsp = (n->arch.flags & TF_kernel_mode) ? (unsigned long *)regs->rsp : @@ -666,7 +666,7 @@ static void clear_segments(void) long do_switch_to_user(void) { - struct cpu_user_regs *regs = get_cpu_user_regs(); + struct cpu_user_regs *regs = guest_cpu_user_regs(); struct switch_to_user stu; struct exec_domain *ed = current; @@ -715,7 +715,7 @@ static inline void switch_kernel_stack(struct exec_domain *n, unsigned int cpu) static void __context_switch(void) { - struct cpu_user_regs *stack_regs = get_cpu_user_regs(); + struct cpu_user_regs *stack_regs = guest_cpu_user_regs(); unsigned int cpu = smp_processor_id(); struct exec_domain *p = percpu_ctxt[cpu].curr_ed; struct exec_domain *n = current; @@ -851,7 +851,7 @@ unsigned long __hypercall_create_continuation( } else { - regs = get_cpu_user_regs(); + regs = guest_cpu_user_regs(); #if defined(__i386__) regs->eax = op; regs->eip -= 2; /* re-execute 'int 0x82' */ diff --git a/xen/arch/x86/mm.c b/xen/arch/x86/mm.c index ef1aaf379c..afbdeaa81d 100644 --- a/xen/arch/x86/mm.c +++ b/xen/arch/x86/mm.c @@ -2836,7 +2836,7 @@ int ptwr_do_page_fault(struct domain *d, unsigned long addr) return EXCRET_fault_fixed; emulate: - if ( x86_emulate_memop(get_cpu_user_regs(), addr, + if ( x86_emulate_memop(guest_cpu_user_regs(), addr, &ptwr_mem_emulator, BITS_PER_LONG/8) ) return 0; perfc_incrc(ptwr_emulations); diff --git a/xen/arch/x86/traps.c b/xen/arch/x86/traps.c index 2838e28a35..fc723bf998 100644 --- a/xen/arch/x86/traps.c +++ b/xen/arch/x86/traps.c @@ -90,6 +90,97 @@ asmlinkage void alignment_check(void); asmlinkage void spurious_interrupt_bug(void); asmlinkage void machine_check(void); +static int debug_stack_lines = 20; +integer_param("debug_stack_lines", debug_stack_lines); + +static inline int kernel_text_address(unsigned long addr) +{ + if (addr >= (unsigned long) &_stext && + addr <= (unsigned long) &_etext) + return 1; + return 0; + +} + +void show_guest_stack(void) +{ + int i; + struct cpu_user_regs *regs = guest_cpu_user_regs(); + unsigned long *stack = (unsigned long *)regs->esp, addr; + + printk("Guest stack trace from "__OP"sp=%p:\n ", stack); + + for ( i = 0; i < (debug_stack_lines*8); i++ ) + { + if ( ((long)stack & (STACK_SIZE-1)) == 0 ) + break; + if ( get_user(addr, stack) ) + { + if ( i != 0 ) + printk("\n "); + printk("Fault while accessing guest memory."); + i = 1; + break; + } + if ( (i != 0) && ((i % 8) == 0) ) + printk("\n "); + printk("%p ", _p(addr)); + stack++; + } + if ( i == 0 ) + printk("Stack empty."); + printk("\n"); +} + +void show_trace(unsigned long *esp) +{ + unsigned long *stack = esp, addr; + int i = 0; + + printk("Xen call trace from "__OP"sp=%p:\n ", stack); + + while ( ((long) stack & (STACK_SIZE-1)) != 0 ) + { + addr = *stack++; + if ( kernel_text_address(addr) ) + { + if ( (i != 0) && ((i % 6) == 0) ) + printk("\n "); + printk("[<%p>] ", _p(addr)); + i++; + } + } + if ( i == 0 ) + printk("Trace empty."); + printk("\n"); +} + +void show_stack(unsigned long *esp) +{ + unsigned long *stack = esp, addr; + int i; + + printk("Xen stack trace from "__OP"sp=%p:\n ", stack); + + for ( i = 0; i < (debug_stack_lines*8); i++ ) + { + if ( ((long)stack & (STACK_SIZE-1)) == 0 ) + break; + if ( (i != 0) && ((i % 8) == 0) ) + printk("\n "); + addr = *stack++; + if ( kernel_text_address(addr) ) + printk("[%p] ", _p(addr)); + else + printk("%p ", _p(addr)); + } + if ( i == 0 ) + printk("Stack empty."); + printk("\n"); + + show_trace(esp); +} + /* * This is called for faults at very unexpected times (e.g., when interrupts * are disabled). In such situations we can't do much that is safe. We try to diff --git a/xen/arch/x86/vmx_intercept.c b/xen/arch/x86/vmx_intercept.c index e23ac6b9f1..84f997eb63 100644 --- a/xen/arch/x86/vmx_intercept.c +++ b/xen/arch/x86/vmx_intercept.c @@ -140,7 +140,7 @@ static int pit_read_io(struct vmx_virpit_t *vpit) /* vmx_io_assist light-weight version, specific to PIT DM */ static void resume_pit_io(ioreq_t *p) { - struct cpu_user_regs *regs = get_cpu_user_regs(); + struct cpu_user_regs *regs = guest_cpu_user_regs(); unsigned long old_eax = regs->eax; p->state = STATE_INVALID; diff --git a/xen/arch/x86/vmx_io.c b/xen/arch/x86/vmx_io.c index 49742286c5..fbd347e48b 100644 --- a/xen/arch/x86/vmx_io.c +++ b/xen/arch/x86/vmx_io.c @@ -187,7 +187,7 @@ void vmx_io_assist(struct exec_domain *ed) vcpu_iodata_t *vio; ioreq_t *p; struct domain *d = ed->domain; - struct cpu_user_regs *regs = get_cpu_user_regs(); + struct cpu_user_regs *regs = guest_cpu_user_regs(); unsigned long old_eax; int sign; struct mi_per_cpu_info *mpci_p; diff --git a/xen/arch/x86/vmx_vmcs.c b/xen/arch/x86/vmx_vmcs.c index 9566e60d9d..b4906bf905 100644 --- a/xen/arch/x86/vmx_vmcs.c +++ b/xen/arch/x86/vmx_vmcs.c @@ -162,7 +162,7 @@ void vmx_do_launch(struct exec_domain *ed) struct Xgt_desc_struct desc; unsigned long pfn = 0; struct pfn_info *page; - struct cpu_user_regs *regs = get_cpu_user_regs(); + struct cpu_user_regs *regs = guest_cpu_user_regs(); vmx_stts(); set_bit(_VCPUF_guest_stts, &ed->vcpu_flags); diff --git a/xen/arch/x86/x86_32/traps.c b/xen/arch/x86/x86_32/traps.c index d3453802b9..9f924831ef 100644 --- a/xen/arch/x86/x86_32/traps.c +++ b/xen/arch/x86/x86_32/traps.c @@ -15,81 +15,6 @@ /* All CPUs have their own IDT to allow set_fast_trap(). */ idt_entry_t *idt_tables[NR_CPUS] = { 0 }; -static int kstack_depth_to_print = 8*20; - -static inline int kernel_text_address(unsigned long addr) -{ - if (addr >= (unsigned long) &_stext && - addr <= (unsigned long) &_etext) - return 1; - return 0; - -} - -void show_guest_stack(void) -{ - int i; - struct cpu_user_regs *regs = get_cpu_user_regs(); - unsigned long *stack = (unsigned long *)regs->esp; - - printk("Guest EIP is %08x\n ", regs->eip); - - for ( i = 0; i < kstack_depth_to_print; i++ ) - { - if ( ((long)stack & (STACK_SIZE-1)) == 0 ) - break; - if ( i && ((i % 8) == 0) ) - printk("\n "); - printk("%08lx ", *stack++); - } - printk("\n"); - -} - -void show_trace(unsigned long *esp) -{ - unsigned long *stack, addr; - int i; - - printk("Call Trace from ESP=%p:\n ", esp); - stack = esp; - i = 0; - while (((long) stack & (STACK_SIZE-1)) != 0) { - addr = *stack++; - if (kernel_text_address(addr)) { - if (i && ((i % 6) == 0)) - printk("\n "); - printk("[<%08lx>] ", addr); - i++; - } - } - printk("\n"); -} - -void show_stack(unsigned long *esp) -{ - unsigned long *stack; - int i; - - printk("Stack trace from ESP=%p:\n ", esp); - - stack = esp; - for ( i = 0; i < kstack_depth_to_print; i++ ) - { - if ( ((long)stack & (STACK_SIZE-1)) == 0 ) - break; - if ( i && ((i % 8) == 0) ) - printk("\n "); - if ( kernel_text_address(*stack) ) - printk("[%08lx] ", *stack++); - else - printk("%08lx ", *stack++); - } - printk("\n"); - - show_trace( esp ); -} - void show_registers(struct cpu_user_regs *regs) { unsigned long ss, ds, es, fs, gs, cs; diff --git a/xen/arch/x86/x86_64/traps.c b/xen/arch/x86/x86_64/traps.c index 33475b3af0..d48ae32fde 100644 --- a/xen/arch/x86/x86_64/traps.c +++ b/xen/arch/x86/x86_64/traps.c @@ -10,81 +10,6 @@ #include #include -static int kstack_depth_to_print = 8*20; - -static inline int kernel_text_address(unsigned long addr) -{ - if (addr >= (unsigned long) &_stext && - addr <= (unsigned long) &_etext) - return 1; - return 0; - -} - -void show_guest_stack(void) -{ - int i; - struct cpu_user_regs *regs = get_cpu_user_regs(); - unsigned long *stack = (unsigned long *)regs->rsp; - - printk("Guest RIP is %016lx\n ", regs->rip); - - for ( i = 0; i < kstack_depth_to_print; i++ ) - { - if ( ((long)stack & (STACK_SIZE-1)) == 0 ) - break; - if ( i && ((i % 8) == 0) ) - printk("\n "); - printk("%016lx ", *stack++); - } - printk("\n"); - -} - -void show_trace(unsigned long *rsp) -{ - unsigned long *stack, addr; - int i; - - printk("Call Trace from RSP=%p:\n ", rsp); - stack = rsp; - i = 0; - while (((long) stack & (STACK_SIZE-1)) != 0) { - addr = *stack++; - if (kernel_text_address(addr)) { - if (i && ((i % 6) == 0)) - printk("\n "); - printk("[<%016lx>] ", addr); - i++; - } - } - printk("\n"); -} - -void show_stack(unsigned long *rsp) -{ - unsigned long *stack; - int i; - - printk("Stack trace from RSP=%p:\n ", rsp); - - stack = rsp; - for ( i = 0; i < kstack_depth_to_print; i++ ) - { - if ( ((long)stack & (STACK_SIZE-1)) == 0 ) - break; - if ( i && ((i % 8) == 0) ) - printk("\n "); - if ( kernel_text_address(*stack) ) - printk("[%016lx] ", *stack++); - else - printk("%016lx ", *stack++); - } - printk("\n"); - - show_trace(rsp); -} - void show_registers(struct cpu_user_regs *regs) { printk("CPU: %d\nEIP: %04lx:[<%016lx>] \nEFLAGS: %016lx\n", @@ -99,6 +24,8 @@ void show_registers(struct cpu_user_regs *regs) regs->r12, regs->r13, regs->r14, regs->r15); show_stack((unsigned long *)regs->rsp); + if ( GUEST_MODE(regs) ) + show_guest_stack(); } void show_page_walk(unsigned long addr) diff --git a/xen/common/domain.c b/xen/common/domain.c index db331a5e14..819bd01ca0 100644 --- a/xen/common/domain.c +++ b/xen/common/domain.c @@ -122,7 +122,10 @@ void domain_crash(void) struct domain *d = current->domain; if ( d->domain_id == 0 ) - BUG(); + { + show_registers(guest_cpu_user_regs()); + panic("Domain 0 crashed!\n"); + } set_bit(_DOMF_crashed, &d->domain_flags); diff --git a/xen/common/schedule.c b/xen/common/schedule.c index bcb6a06e6e..d7ba0a078c 100644 --- a/xen/common/schedule.c +++ b/xen/common/schedule.c @@ -282,7 +282,6 @@ long do_sched_op(unsigned long op) switch ( op & SCHEDOP_cmdmask ) { - case SCHEDOP_yield: { ret = do_yield(); @@ -297,7 +296,8 @@ long do_sched_op(unsigned long op) case SCHEDOP_shutdown: { - TRACE_3D(TRC_SCHED_SHUTDOWN, current->domain->domain_id, current->vcpu_id, + TRACE_3D(TRC_SCHED_SHUTDOWN, + current->domain->domain_id, current->vcpu_id, (op >> SCHEDOP_reasonshift)); domain_shutdown((u8)(op >> SCHEDOP_reasonshift)); break; diff --git a/xen/drivers/char/console.c b/xen/drivers/char/console.c index 73394c1973..c873901e7b 100644 --- a/xen/drivers/char/console.c +++ b/xen/drivers/char/console.c @@ -496,6 +496,7 @@ int debugtrace_send_to_console; static char *debugtrace_buf; /* Debug-trace buffer */ static unsigned int debugtrace_prd; /* Producer index */ static unsigned int debugtrace_kilobytes = 128, debugtrace_bytes; +static unsigned int debugtrace_used; static spinlock_t debugtrace_lock = SPIN_LOCK_UNLOCKED; integer_param("debugtrace", debugtrace_kilobytes); @@ -504,7 +505,7 @@ void debugtrace_dump(void) int _watchdog_on = watchdog_on; unsigned long flags; - if ( debugtrace_bytes == 0 ) + if ( (debugtrace_bytes == 0) || !debugtrace_used ) return; /* Watchdog can trigger if we print a really large buffer. */ @@ -542,6 +543,8 @@ void debugtrace_printk(const char *fmt, ...) if ( debugtrace_bytes == 0 ) return; + debugtrace_used = 1; + spin_lock_irqsave(&debugtrace_lock, flags); ASSERT(debugtrace_buf[debugtrace_bytes - 1] == 0); @@ -608,7 +611,7 @@ __initcall(debugtrace_init); void panic(const char *fmt, ...) { va_list args; - char buf[128]; + char buf[128], cpustr[10]; unsigned long flags; extern void machine_restart(char *); @@ -623,11 +626,11 @@ void panic(const char *fmt, ...) /* Spit out multiline message in one go. */ spin_lock_irqsave(&console_lock, flags); __putstr("\n****************************************\n"); + __putstr("Panic on CPU"); + sprintf(cpustr, "%d", smp_processor_id()); + __putstr(cpustr); + __putstr(":\n"); __putstr(buf); - __putstr("Aieee! CPU"); - sprintf(buf, "%d", smp_processor_id()); - __putstr(buf); - __putstr(" is toast...\n"); __putstr("****************************************\n\n"); __putstr("Reboot in five seconds...\n"); spin_unlock_irqrestore(&console_lock, flags); diff --git a/xen/include/asm-x86/x86_32/current.h b/xen/include/asm-x86/x86_32/current.h index fe7db8a14c..337d4e1d52 100644 --- a/xen/include/asm-x86/x86_32/current.h +++ b/xen/include/asm-x86/x86_32/current.h @@ -23,7 +23,7 @@ static inline void set_current(struct exec_domain *ed) : : "r" (STACK_SIZE-4), "r" (ed) ); } -static inline struct cpu_user_regs *get_cpu_user_regs(void) +static inline struct cpu_user_regs *guest_cpu_user_regs(void) { struct cpu_user_regs *cpu_user_regs; __asm__ ( "andl %%esp,%0; addl %2,%0" @@ -49,7 +49,7 @@ static inline unsigned long get_stack_bottom(void) #define reset_stack_and_jump(__fn) \ __asm__ __volatile__ ( \ "movl %0,%%esp; jmp "STR(__fn) \ - : : "r" (get_cpu_user_regs()) ) + : : "r" (guest_cpu_user_regs()) ) #define schedule_tail(_ed) ((_ed)->arch.schedule_tail)(_ed) diff --git a/xen/include/asm-x86/x86_64/current.h b/xen/include/asm-x86/x86_64/current.h index bb6a397422..1b06998bb2 100644 --- a/xen/include/asm-x86/x86_64/current.h +++ b/xen/include/asm-x86/x86_64/current.h @@ -23,7 +23,7 @@ static inline void set_current(struct exec_domain *ed) : : "r" (STACK_SIZE-8), "r" (ed) ); } -static inline struct cpu_user_regs *get_cpu_user_regs(void) +static inline struct cpu_user_regs *guest_cpu_user_regs(void) { struct cpu_user_regs *cpu_user_regs; __asm__( "andq %%rsp,%0; addq %2,%0" @@ -49,7 +49,7 @@ static inline unsigned long get_stack_bottom(void) #define reset_stack_and_jump(__fn) \ __asm__ __volatile__ ( \ "movq %0,%%rsp; jmp "STR(__fn) \ - : : "r" (get_cpu_user_regs()) ) + : : "r" (guest_cpu_user_regs()) ) #define schedule_tail(_ed) ((_ed)->arch.schedule_tail)(_ed) -- 2.30.2